package com.example.sls.utils;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Hashtable;

/**
 * 二维码
 * 编者：蓝江富
 * 时间：2024/6/14 15:21
 */
public class QRCodeUtil {
  // 编码格式
  private static final String UNICODE="utf-8";
  // 生成二维码图片的格式
  private static final String FORMAT="JPG";
  // 二维码相关尺寸
  private static final int QRCODE_WIDTH=300;
  private static final int QRCODE_HEIGHT=300;
  // LOGO的尺寸
  private static final int LOGO_WIDTH=100;
  private static final int LOGO_HEIGHT=100;

  // 生成二维码图片
  private static BufferedImage createImg(String content,String logoPath) throws WriterException {
    // 用户设置QR二维码参数
    Hashtable<EncodeHintType,Object>hints=new Hashtable<EncodeHintType,Object>();
    // QR二维码的纠错h位最后级别信息
    hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
    // 设置编码格式
    hints.put(EncodeHintType.CHARACTER_SET,UNICODE);
    // Margin 设置位1
    hints.put(EncodeHintType.MARGIN,1);
    // 生成二维码
    BitMatrix bitMatrix=new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE,QRCODE_WIDTH,QRCODE_HEIGHT,hints);

    int width=bitMatrix.getWidth();
    int height=bitMatrix.getHeight();

    // 生成图片
    BufferedImage image=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
    // 开始利用二维码创建图片
    for (int x=0;x<width;x++){
      for (int y=0;y<height;y++){
        image.setRGB(x,y,bitMatrix.get(x,y)?0xFF000000:0xFFFFFFFF);
      }
    }
    if(logoPath==null || "".equals(logoPath)){
      return image;
    }
    System.out.println("根据路径生成图片");
    QRCodeUtil.insertImage(image,logoPath);
    return image;
  }

  public static void encode(String content, String logoPath, OutputStream outputStream) throws WriterException, IOException {
    BufferedImage image=QRCodeUtil.createImg(content,logoPath);
    ImageIO.write(image,FORMAT,outputStream);
  }

  /**
   * 将新的logo图片插入到二维码中
   * @param bufferedImage 生成的二维码图片
   * @param logoPath 插入图片的路径
   */
  private static void insertImage(BufferedImage bufferedImage,String logoPath){
    System.out.println("图片路径："+logoPath);
    File file=new File(logoPath);
    if (!file.exists()){
      System.out.println("没有发现文件信息");
    }
    try {
      // 读取要插入二维码的图片信息
      Image src=ImageIO.read(new File(logoPath));
      int width=src.getWidth(null);
      int height=src.getHeight(null);
      if (width>LOGO_WIDTH){
        width=LOGO_WIDTH;
      }
      if (height>LOGO_HEIGHT){
      height=LOGO_HEIGHT;
      }
      // 图像进行缩放
      Image image=src.getScaledInstance(width,height,Image.SCALE_SMOOTH);
      // 将新的图片存放到二维码
      BufferedImage tag=new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
      // 绘制
      Graphics g=tag.getGraphics();
      // 绘制缩小后的图片尺寸
      g.drawImage(image,0,0,null);
      // 清理对象
      g.dispose();

      // 插入logo
      Graphics2D graphics2D=bufferedImage.createGraphics();
      int x=(QRCODE_WIDTH-width)/2;
      int y=(QRCODE_HEIGHT-height)/2;

      // 开始绘制图
      graphics2D.drawImage(src,x,y,width,height,null);
      // 绘制圆角
      Shape shape=new RoundRectangle2D.Float(x,y,width,width,6,6);
      // 设置画笔
      graphics2D.setStroke(new BasicStroke(3f));
      // 绘制图片
      graphics2D.draw(shape);
      graphics2D.dispose();
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }
}
